package com.wx.service.impl;

import com.google.common.collect.Lists;
import com.wx.common.SecurityUser;
import com.wx.constants.Constants;
import com.wx.domain.dto.ActionBindRoleDto;
import com.wx.domain.dto.PermissionDto;
import com.wx.domain.vo.AuthorityTreeVo;
import com.wx.entity.SysAuthority;
import com.wx.entity.SysMenu;
import com.wx.entity.SysRoleAuthority;
import com.wx.exception.BusinessException;
import com.wx.mapper.SysAuthorityMapper;
import com.wx.service.SysAuthorityService;
import com.wx.service.SysMenuService;
import com.wx.service.SysRoleAuthorityService;
import com.wx.utils.SnowFlakeUtil;
import com.wx.utils.TreeUtil;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>Title:      AuthorityServiceImpl. </p>
 * <p>Description TODO </p>
 * <p>Copyright: Copyright (c) 2016</p>
 * <p>Company:     医百科技有限公司</p>
 *
 * @author         <a href="xinglinglove1029@163.com"/>杨文生</a>
 * @since      2019/8/14 22:10
 */
@Service
public class SysAuthorityServiceImpl extends BaseServiceImpl<SysAuthority> implements SysAuthorityService {

    @Resource
    private SysAuthorityMapper authorityMapper;


    @Resource
    private SysRoleAuthorityService roleAuthorityService;

    @Resource
    private SysMenuService sysMenuService;


    @Override
    public List<SysAuthority> getOwnAuthority(String userId) {
        return authorityMapper.getOwnAuthority(userId);
    }

    @Override
    @Transactional
    public int saveAuthorityInfo(SysAuthority authority, SecurityUser user) {
        authority.setId(SnowFlakeUtil.getStringId());
//        authority.setAuthorityCode(PingYinUtil.getPingYin(authority.getAuthorityName()));
        authority.setId(SnowFlakeUtil.getStringId());
        authorityMapper.insertSelective(authority);
        return authorityMapper.insertSelective(authority);
    }

    @Override
    public int modifyAuthority(SysAuthority authority, SecurityUser user) {
        SysAuthority queryAuthority = new SysAuthority();
        queryAuthority.setId(authority.getId());
        queryAuthority.setDelFlag(Constants.DELETE_NO);
        SysAuthority auth = authorityMapper.selectOne(queryAuthority);
        if (Objects.isNull(auth)) {
            throw new BusinessException("权限信息不存在");
        }
        authority.setUpdateDate(new Date());
        return authorityMapper.updateByPrimaryKeySelective(authority);
    }

    @Override
    public int disableAuthorityById(String id, SecurityUser authUserDto) {
        SysAuthority queryAuthority = new SysAuthority();
        queryAuthority.setId(id);
        queryAuthority.setDelFlag(Constants.DELETE_NO);
        SysAuthority authority = authorityMapper.selectOne(queryAuthority);
        if (Objects.isNull(authority)) {
            throw new BusinessException("权限信息不存在");
        }
        if (!Constants.ENABLE.equals(authority.getStatus())) {
            throw new BusinessException("不是启用状态的不能禁用");
        }
        queryAuthority.setStatus(Constants.DISABLE);
        queryAuthority.setUpdater(authUserDto.getUsername());
        queryAuthority.setUpdateBy(authUserDto.getUserId());
        queryAuthority.setUpdateDate(new Date());
        return authorityMapper.updateByPrimaryKeySelective(queryAuthority);
    }

    @Override
    public int enableAuthorityById(String id, SecurityUser authUserDto) {
        SysAuthority queryAuthority = new SysAuthority();
        queryAuthority.setId(id);
        queryAuthority.setDelFlag(Constants.DELETE_NO);
        SysAuthority authority = authorityMapper.selectOne(queryAuthority);
        if (Objects.isNull(authority)) {
            throw new BusinessException("权限信息不存在");
        }
        if (!Constants.DISABLE.equals(authority.getStatus())) {
            throw new BusinessException("不是禁用状态的不能启用");
        }
        queryAuthority.setStatus(Constants.ENABLE);
        queryAuthority.setUpdater(authUserDto.getUsername());
        queryAuthority.setUpdateBy(authUserDto.getUserId());
        queryAuthority.setUpdateDate(new Date());
        return authorityMapper.updateByPrimaryKeySelective(queryAuthority);
    }

    @Override
    public int deleteAuthorityById(String id, SecurityUser authUserDto) {
        SysAuthority queryAuthority = new SysAuthority();
        queryAuthority.setId(id);
        queryAuthority.setDelFlag(Constants.DELETE_NO);
        SysAuthority authority = authorityMapper.selectOne(queryAuthority);
        if (Objects.isNull(authority)) {
            throw new BusinessException("权限信息不存在");
        }
        queryAuthority.setDelFlag(Constants.DELETE_YES);
        queryAuthority.setUpdater(authUserDto.getUsername());
        queryAuthority.setUpdateBy(authUserDto.getUserId());
        queryAuthority.setUpdateDate(new Date());
        return authorityMapper.updateByPrimaryKeySelective(queryAuthority);
    }

    @Override
    public List<SysAuthority> queryListPage(SysAuthority authority) {
        return authorityMapper.queryListPage(authority);
    }

    @Override
    public List<AuthorityTreeVo> getAllAuthorityInfoList() {
        // 查询所有菜单信息
        List<SysMenu> menuList = sysMenuService.selectAll();

        // 查询所有权限信息
        List<SysAuthority> authorityList = authorityMapper.selectAll();

        // 合并菜单和权限数据
        List<AuthorityTreeVo> authorityTreeVos = this.buildResourceData(menuList, authorityList);
        return TreeUtil.bulid(authorityTreeVos, Constants.Sys.ROOT_PARENTID);
    }


    private List<AuthorityTreeVo> buildResourceData(List<SysMenu> menuList, List<SysAuthority> authorityList) {
        List<AuthorityTreeVo> authorityTreeVos = Lists.newArrayList();
        AuthorityTreeVo authorityTreeVo;
        for (SysMenu menu : menuList) {
            authorityTreeVo = new AuthorityTreeVo();
            authorityTreeVo.setId(menu.getId());
            authorityTreeVo.setParentId(menu.getPid());
            authorityTreeVo.setResourceName(menu.getMenuName());
            authorityTreeVo.setType("1");
            authorityTreeVos.add(authorityTreeVo);
        }
        if (authorityList != null) {
            for (SysAuthority authority : authorityList) {
                authorityTreeVo = new AuthorityTreeVo();
                authorityTreeVo.setId(authority.getId());
                authorityTreeVo.setParentId(authority.getMenuId());
                authorityTreeVo.setResourceName(authority.getAuthorityName());
                authorityTreeVo.setType("2");
                authorityTreeVos.add(authorityTreeVo);
            }
        }
        return authorityTreeVos;
    }
    @Override
    public List<SysAuthority> getBindPermissionByRoleIds(List<String> roleIds) {
        return authorityMapper.getBindPermissionByRoleIds(roleIds);
    }


    @Override
    public Collection<GrantedAuthority> loadUserAuthorities(List<String> roleIds) {
        List<SysAuthority> ownAuthList = authorityMapper.getBindPermissionByRoleIds(roleIds);
        List<GrantedAuthority> authList = Lists.newArrayList();
        for (SysAuthority authority : ownAuthList) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authority.getUrl());
            authList.add(grantedAuthority);
        }
        return authList;
    }

    @Override
    public List<String> getAllResourceIdList() {
        List<String> idList = Lists.newArrayList();
        // 查询所有菜单信息
        List<SysMenu> menuList = sysMenuService.selectAll();
        List<String> menuIds = menuList.stream().map(SysMenu::getId).collect(Collectors.toList());

        // 查询所有权限信息
        List<SysAuthority> authorityList = authorityMapper.selectAll();
        List<String> authorityIds = authorityList.stream().map(SysAuthority::getId).collect(Collectors.toList());
        idList.addAll(menuIds);
        idList.addAll(authorityIds);
        return idList;
    }

    @Override
    public List<PermissionDto> findAllPermission() {
        return authorityMapper.findAllPermission();
    }

    @Override
    public List<String> getBindRoleListByActionId(String actionId) {
        return roleAuthorityService.getBindRoleListByActionId(actionId);
    }

    @Override
    @Transactional
    public void bindRole(ActionBindRoleDto actionBindRoleDto) {
        // 先删除原来的绑定关系
        roleAuthorityService.deleteByActionId(actionBindRoleDto.getActionId());
        if(actionBindRoleDto.getRoleIdList().size() == 0){
          throw new BusinessException("角色不能为空");
        }
        List<SysRoleAuthority> list = Lists.newArrayList();
        SysRoleAuthority authority = null;
        for (String roleId : actionBindRoleDto.getRoleIdList()) {
            authority = new SysRoleAuthority();
            authority.setRoleId(roleId);
            authority.setAuthorityId(actionBindRoleDto.getActionId());
            list.add(authority);
        }
        roleAuthorityService.batchSave(list);
    }
}
